--[[============================================================================
main.lua
============================================================================]]--

require "sha1"
require "base64"
require "WebsocketMessage"
require "CommandRunner"

class "WebSocketServer"
  local parser

  function WebSocketServer:__init(port)
   -- create a server socket
   local server, socket_error = renoise.Socket.create_server(port)
     
   if socket_error then 
     app:show_warning(
       "Failed to start the WebControl server: " .. socket_error)
   else
     -- start running
     self.server = server
     self.server:run(self)
     print("Server started....")
   end
  end

  function WebSocketServer:socket_error(socket_error)
    renoise.app():show_warning(socket_error)
  end
  
  local function parseHeaders(message)
    local requestHeaders = {}
    for k, v in message:gmatch("([%w-]+): ([^\n\r]*)\r\n") do 
      requestHeaders[k] = v
    end
    return requestHeaders
  end
  
  local function sendHandshake(socket, request)
    local key = request["Sec-WebSocket-Key"]
    local accept = encode_base64(sha1_binary(key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
    local response = "HTTP/1.1 101 Switching Protocols\r\n" ..
      "Upgrade: websocket\r\n" ..
      "Connection: Upgrade\r\n" ..
      "Sec-WebSocket-Accept: " .. accept .. "\r\n\r\n"
    socket:send(response)
  end
  
  local function sendUnauthorized(socket)
    socket:send("HTTP/1.1 403 Forbidden\r\n\r\n")
  end
  
  local function userAuthorization(request)
    --local message = ("A webpage (%s) tries to connect to your Renoise, allow?"):format(request["Origin"])
    --return renoise.app():show_prompt("Connecting...", message, {"Yes", "No"}) == "Yes"
    return true
  end
  
  function WebSocketServer:socket_accepted(socket)
    print(("client %s:%d connected"):format(
      socket.peer_address, socket.peer_port))
  end

  function WebSocketServer:socket_message(socket, message)
    if(message:find("^GET")) then
      local request = parseHeaders(message)
      if (not userAuthorization(request)) then
        sendUnauthorized(socket)
      else
        sendHandshake(socket, request)
      end
    else
      if not parser then
        parser = WebSocketDecoder()
      end
    
      if(parser:decode(message)) then
        local command = parser.buffer
        parser = nil
        local success, result = runCommand(socket, command)
        if(result) then
          socket:send(encodeWebSocketMessage(result))
        end
      end
    end
  end

local WebSocketServer = WebSocketServer(9769)
